# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2021/9/30 10:09
# @Author  : zuodengbo
# @Email   : zuodb@amoydx.com
# @File    : model
# @Software: PyCharm
from tortoise import fields

from commons.models import AbstractBaseModel, TimeMixin
from utils.common import time_now, json_format


class Company(AbstractBaseModel):
    """
    company model
    """
    name = fields.CharField(max_length=32, unique=True, description="公司名称")
    address = fields.CharField(max_length=32, description="公司地址")

    user_company: fields.ReverseRelation["UserJobInfo"]

    def __str__(self):
        return self.name

    class Meta:
        table = "tbl_u_company"


class Department(AbstractBaseModel):
    """
    department model
    """
    name = fields.CharField(max_length=32, unique=True, description="部门名称")
    sup_department: fields.ForeignKeyNullableRelation["Department"] = \
        fields.ForeignKeyField("models.Department", null=True,
                               related_name="up_depart", description="上级部门标识")
    level = fields.IntField(default=1, description="部门等级")

    up_depart: fields.ReverseRelation["Department"]
    user_department: fields.ReverseRelation["UserJobInfo"]

    def __str__(self):
        return self.name

    class Meta:
        table = "tbl_u_department"


class Position(AbstractBaseModel):
    """
    position model
    """
    name = fields.CharField(max_length=32, unique=True, description="职位名称")

    user_position: fields.ReverseRelation["UserJobInfo"]

    def __str__(self):
        return self.name

    class Meta:
        table = "tbl_u_position"


class User(AbstractBaseModel, TimeMixin):
    """
    user model
    """
    STATUS = (
        (0, "禁用"),
        (1, "正常"),
    )
    SUPER = (
        (0, "普通用户"),
        (1, "超级管理员"),
    )

    username = fields.CharField(max_length=20, unique=True, description="用户名")
    name = fields.CharField(max_length=32, description="用户姓名")
    email = fields.CharField(max_length=32, unique=True, description="邮箱")
    phone = fields.CharField(max_length=32, unique=True, description="电话号码")
    password = fields.CharField(max_length=64, description="密码 md5 数据")
    # is_super = fields.IntField(choices=SUPER, default=0, description="是否为超级管理员, 0-普通用户,1-超级管理员")
    status = fields.IntField(choices=STATUS, default=1, description="用户状态, 0-禁用,1-正常")
    age = fields.IntField(max_length=3, null=True, description="年龄")
    gender = fields.CharField(max_length=10, null=True, description="性别")  # 性别
    birthday = fields.DateField(null=True, description="生日")
    address = fields.CharField(max_length=100, null=True, description="地址")
    remark = fields.TextField(null=True, description="备注")

    user_job_info: fields.ReverseRelation["UserJobInfo"]
    user_login_log: fields.ReverseRelation["LoginLog"]
    user_roles: fields.ReverseRelation["UserRole"]

    def __str__(self):
        return f'{self.username}, {self.name}, {self.password}, {self.status}: ' \
               f'{self.age}, {self.gender}, {self.birthday}, {self.address}'
    
    def __json__(self):
        return json_format({
            "id": self.id,
            "username": self.username,
            "name": self.name,
            "email": self.email,
            "phone": self.phone,
            "password": self.password,
            "status": self.status,
            "gender": self.gender,
            "age": self.age,
            "birthday": self.birthday.strftime("%Y-%m-%d") if self.birthday is not None else "",
            "address": self.address,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S") if self.create_time is not None else "",
            "update_time": self.update_time.strftime("%Y-%m-%d %H:%M:%S")if self.update_time is not None else "",
            "remark": self.remark
        }, default=str)

    class Meta:
        table = "tbl_u_user"
        ordering = ["username", "-create_time"]  # 默认排序


class UserJobInfo(AbstractBaseModel, TimeMixin):
    """
    user job info model
    """
    STATUS = (
        (0, "离职"),
        (1, "在职")
    )
    LEVEL = (
        (1, "初级(primary)"),
        (2, "中级(middle)"),
        (3, "高级(senior)"),
        (4, "资深(professional)")
    )
    user: fields.OneToOneRelation[User] = fields.OneToOneField(
        "models.User", related_name="user_job_info", description="用户标识")
    company: fields.ForeignKeyRelation[Company] = fields.ForeignKeyField(
        "models.Company", related_name="user_company", description="公司标识")
    department: fields.ForeignKeyRelation[Department] = fields.ForeignKeyField(
        "models.Department", related_name="user_department", description="部门标识")
    position: fields.ForeignKeyRelation[Position] = fields.ForeignKeyField(
        "models.Position", related_name="user_position", description="职位标识")
    job_num = fields.CharField(max_length=10, unique=True, index=True, description="工号")
    status = fields.IntField(choices=STATUS, default=1, description="状态")
    level = fields.IntField(choices=LEVEL, default=1,
                            description="级别，1-初级(primary), 2-中级(middle), 3-高级(senior), 4-资深(professional)")

    class Meta:
        table = "tbl_u_user_job_info"


class LoginLog(AbstractBaseModel):
    """
    login log model
    """
    user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="user_login_log", description="用户标识")
    login_time = fields.DatetimeField(auto_now_add=True, default=time_now(), description="登录时间")
    logout_time = fields.DatetimeField(null=True, description="登出时间")

    class Meta:
        table = "tbl_u_login_log"


class VerifyCode(AbstractBaseModel):
    """
    verify code model
    """
    STATUS = (
        (1, "未验证"),
        (2, "已验证")
    )
    key = fields.CharField(max_length=6, description="查询字段")
    code = fields.CharField(max_length=6, description="验证码")
    valid_time = fields.DatetimeField(description="有效时间")
    status = fields.IntField(choices=STATUS, default=1, description="验证码状态，1-未验证，2-已验证")

    class Meta:
        table = "tbl_u_verify_code"
        indexes = ("key",)  # 索引字段


class Role(AbstractBaseModel, TimeMixin):
    """
    role model
    """
    STATUS = (
        (0, "冻结"),
        (1, "可用")
    )
    name = fields.CharField(max_length=32, unique=True, description="角色名称")
    code = fields.CharField(max_length=32, unique=True, description="角色代码")
    status = fields.IntField(choices=STATUS, default=1, description="角色状态, 0-冻结,1-可用")
    creator: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="role_creator", null=True, description="角色创建者")

    roles: fields.ReverseRelation["UserRole"]
    role_authority: fields.ReverseRelation["RoleAuthority"]

    def __str__(self):
        return f"{self.name}, {self.code}"

    def __json__(self):
        return json_format({
            "id": self.id,
            "name": self.name,
            "code": self.code,
            "status": self.status,
            "creator": self.creator_id,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S") if self.create_time is not None else "",
            "update_time": self.update_time.strftime("%Y-%m-%d %H:%M:%S")if self.update_time is not None else "",
        }, default=str)

    class Meta:
        table = "tbl_u_role"
        indexes = ("code", "name")  # 索引字段


class Authority(AbstractBaseModel, TimeMixin):
    """
    authority model
    """
    TYPE = (
        (1, "目录"),  # 数据权限
        (2, "菜单"),  # 页面权限
        (3, "按钮"),  # 操作权限
    )
    STATUS = (
        (0, "冻结"),
        (1, "可用")
    )
    name = fields.CharField(max_length=32, unique=True, description="权限名称")
    code = fields.CharField(max_length=64, unique=True, description="权限代码")
    path = fields.CharField(max_length=128, unique=True, null=True, description="前端接口地址")
    uri = fields.CharField(max_length=128, unique=True, null=True, description="后端接口地址")
    icon = fields.CharField(max_length=128, null=True, description="图标,如element ui icon元素")
    type = fields.IntField(choices=TYPE, description="权限类型, 1-目录(数据),2-菜单(页面),3-按钮(操作)")
    status = fields.IntField(choices=STATUS, default=1, description="权限状态, 0-冻结,1-可用")
    parent: fields.ForeignKeyNullableRelation["Authority"] = \
        fields.ForeignKeyField("models.Authority", null=True,
                               related_name="up_authority", description="上级权限标识")

    up_authority: fields.ReverseRelation["Authority"]
    authority: fields.ReverseRelation["RoleAuthority"]

    def __str__(self):
        return f"{self.name}, {self.code}"

    def __json__(self):
        return json_format({
            "id": self.id,
            "name": self.name,
            "code": self.code,
            "uri": self.uri,
            "path": self.path,
            "icon": self.icon,
            "status": self.status,
            "type": self.type,
            "parent_id": self.parent_id,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S") if self.create_time is not None else "",
            "update_time": self.update_time.strftime("%Y-%m-%d %H:%M:%S")if self.update_time is not None else "",
        }, default=str)

    class Meta:
        table = "tbl_u_authority"
        indexes = ("code", "name")  # 索引字段


class UserRole(AbstractBaseModel):
    """
    user role model
    """
    STATUS = (
        (0, "冻结"),
        (1, "可用")
    )
    user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="user_roles", description="用户标识")
    role: fields.ForeignKeyRelation[Role] = fields.ForeignKeyField(
        "models.Role", related_name="roles", description="角色标识")
    status = fields.IntField(choices=STATUS, default=1, description="权限状态, 0-冻结,1-可用")

    class Meta:
        table = "tbl_u_user_role"


class RoleAuthority(AbstractBaseModel):
    """
    role authority model
    """
    STATUS = (
        (0, "冻结"),
        (1, "可用")
    )
    role: fields.ForeignKeyRelation[Role] = fields.ForeignKeyField(
        "models.Role", related_name="role_authority", description="角色标识")
    authority: fields.ForeignKeyRelation[Authority] = fields.ForeignKeyField(
        "models.Authority", related_name="authority", description="权限标识")
    status = fields.IntField(choices=STATUS, default=1, description="权限状态, 0-冻结,1-可用")

    class Meta:
        table = "tbl_u_role_authority"

